home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
e
/
jrhrkrm2.lzh
/
RKRM_PartTwo
/
Console
/
Console.e
< prev
Wrap
Text File
|
1995-09-20
|
8KB
|
231 lines
-> Console.e
->
-> Example of opening a window and using the console device to send text and
-> control sequences to it. The example can be easily modified to do
-> additional control sequences.
->>> Header (globals)
OPT PREPROCESS
MODULE 'devices/console',
'exec/io',
'exec/ports',
'intuition/intuition',
'intuition/screens',
'amigalib/io',
'amigalib/ports'
ENUM ERR_NONE, ERR_DEV, ERR_IO, ERR_PORT
RAISE ERR_DEV IF OpenDevice()<>0
-> Note - using two character <CSI> ESC[. Hex 9B could be used instead
#define RESETCON '\ec'
#define CURSOFF '\e[0 p'
#define CURSON '\e[ p'
#define DELCHAR '\e[P'
-> SGR (set graphic rendition)
#define COLOR02 '\e[32m'
#define COLOR03 '\e[33m'
#define ITALICS '\e[3m'
#define BOLD '\e[1m'
#define UNDERLINE '\e[4m'
#define NORMAL '\e[0m'
DEF win=NIL:PTR TO window, writeReq=NIL:PTR TO iostd, writePort=NIL:PTR TO mp,
readReq=NIL:PTR TO iostd, readPort=NIL:PTR TO mp, openedConsole=FALSE
->>>
->>> PROC main()
PROC main() HANDLE
DEF winmsg:PTR TO intuimessage, signals, conreadsig, windowsig, lch,
inControl=0, going=TRUE, ch, ibuf, obuf[200]:STRING, error, class
-> Create reply port and io block for writing to console
IF NIL=(writePort:=createPort('RKM.console.write', 0)) THEN Raise(ERR_PORT)
IF NIL=(writeReq:=createExtIO(writePort, SIZEOF iostd)) THEN Raise(ERR_IO)
-> Create reply port and io block for reading from console
IF NIL=(readPort:=createPort('RKM.console.read', 0)) THEN Raise(ERR_PORT)
IF NIL=(readReq:=createExtIO(readPort, SIZEOF iostd)) THEN Raise(ERR_IO)
-> Open a window
win:=OpenWindow([10, 10, 620, 180, -1, -1, IDCMP_CLOSEWINDOW,
WFLG_DEPTHGADGET OR WFLG_SIZEGADGET OR WFLG_DRAGBAR OR
WFLG_CLOSEGADGET OR WFLG_SMART_REFRESH OR WFLG_ACTIVATE,
NIL, NIL, 'Console Test', NIL, NIL,
100, 45, 640, 200, WBENCHSCREEN]:nw)
-> Now, attach a console to the window
openConsole(writeReq, readReq, win)
openedConsole:=TRUE
-> Demonstrate some console escape sequences
conPuts(writeReq, 'Here''s some normal text\n')
StringF(obuf, '\s\sHere''s some text in color 3 and italics\n',
COLOR03, ITALICS)
conPuts(writeReq, obuf)
conPuts(writeReq, NORMAL)
Delay(50) -> Delay for dramatic effect
conPuts(writeReq, 'We will now delete this asterisk =*=')
Delay(50)
conPuts(writeReq, {bspace}) -> Backspace twice
Delay(50)
conPuts(writeReq, DELCHAR) -> Delete the character
Delay(50)
queueRead(readReq, {ibuf}) -> Send the first console read request
conPuts(writeReq, '\n\nNow reading console\n')
conPuts(writeReq, 'Type some keys. Close window when done.\n\n')
conreadsig:=Shl(1, readPort.sigbit)
windowsig:=Shl(1, win.userport.sigbit)
WHILE going
-> A character, or an IDCMP msg, or both could wake us up
signals:=Wait(conreadsig OR windowsig)
-> If a console signal was received, get the character
IF signals AND conreadsig
IF -1<>(lch:=conMayGetChar(readPort, {ibuf}))
ch:=lch
-> Show hex and ascii (if printable) for char we got. If you want to
-> parse received control sequences, such as function or Help keys,
-> you would buffer control sequences as you receive them, starting to
-> buffer whenever you receive $9B (or $1B[ for user-typed sequences)
-> and ending when you receive a valid terminating character for the
-> type of control sequence you are receiving. For CSI sequences,
-> valid terminating characters are generally $40 through $7E. In our
-> example, InControl has the following values: 0 = no, 1 = have $1B,
-> 2 = have $9B OR $1B and [, 3 = now inside control sequence,
-> -1 = normal end esc, -2 = non-CSI(no [) $1B end esc
-> NOTE - a more complex parser is required to recognize other types
-> of control sequences.
-> $1B ESC not followed by "[", is not CSI seq
IF inControl=1 THEN (inControl:=IF ch="[" THEN 2 ELSE -2)
IF (ch=$9B) OR (ch=$1B) -> Control seq starting
inControl:=IF ch=$1B THEN 1 ELSE 2
conPuts(writeReq, '=== Control Seq ===\n')
ENDIF
-> We'll show the value of this char we received
IF ((ch>=$1F) AND (ch<=$7E)) OR (ch>=$A0)
StringF(obuf, 'Received: hex $\z\h[2] = \c\n', ch, ch)
ELSE
StringF(obuf, 'Received: hex $\z\h[2]\n', ch)
ENDIF
conPuts(writeReq, obuf)
ENDIF
ENDIF
-> If IDCMP messages received, handle them
IF signals AND windowsig
-> We have to ReplyMsg these when done with them
WHILE winmsg:=GetMsg(win.userport)
class:=winmsg.class
SELECT class
CASE IDCMP_CLOSEWINDOW
going:=FALSE
ENDSELECT
ReplyMsg(winmsg)
ENDWHILE
ENDIF
ENDWHILE
-> We always have an outstanding queued read request so we must abort it if
-> it hasn't completed, and we must remove it.
IF CheckIO(readReq)=FALSE THEN AbortIO(readReq)
WaitIO(readReq) -> Clear it from our replyport
EXCEPT DO
IF openedConsole THEN closeConsole(writeReq)
IF win THEN CloseWindow(win)
IF readReq THEN deleteExtIO(readReq)
IF readPort THEN deletePort(readPort)
IF writeReq THEN deleteExtIO(writeReq)
IF writePort THEN deletePort(writePort)
SELECT exception
CASE ERR_DEV; WriteF('Error: could not open console device\n')
CASE ERR_IO; WriteF('Error: could not create I/O\n')
CASE ERR_PORT; WriteF('Error: could not create port\n')
ENDSELECT
ENDPROC
-> E-Note: simple way to get a string with two backspaces
bspace: CHAR 8, 8, 0
->>>
->>> PROC openConsole(writereq:PTR TO iostd, readReq:PTR TO iostd, window)
-> Attach console device to an open Intuition window.
-> E-Note: This function will raise an exception if the console device is not
-> opened correctly.
PROC openConsole(writereq:PTR TO iostd, readreq:PTR TO iostd, window)
DEF error
writereq.data:=window
writereq.length:=SIZEOF window
error:=OpenDevice('console.device', 0, writereq, 0)
readreq.device:=writereq.device -> Clone required parts
readreq.unit:=writereq.unit
ENDPROC error
->>>
->>> PROC closeConsole(writereq)
PROC closeConsole(writereq) IS CloseDevice(writereq)
->>>
->>> PROC conPutChar(writereq:PTR TO iostd, char)
-> Output a single character to a specified console.
PROC conPutChar(writereq:PTR TO iostd, char)
writereq.command:=CMD_WRITE
-> E-Note: use typed list to get address of the CHAR in the LONG 'char'
writereq.data:=[char]:CHAR
writereq.length:=1
DoIO(writereq)
-> Command works because DoIO blocks until command is done (otherwise
-> pointer to string could become invalid in the meantime).
ENDPROC
->>>
->>> PROC conWrite(writereq:PTR TO iostd, string, length)
-> Output a stream of known length to a console.
PROC conWrite(writereq:PTR TO iostd, string, length)
writereq.command:=CMD_WRITE
writereq.data:=string
writereq.length:=length
DoIO(writereq)
ENDPROC
->>>
->>> PROC conPuts(writereq:PTR TO iostd, string)
-> Output a NIL-terminated string of characters to a console.
PROC conPuts(writereq:PTR TO iostd, string)
writereq.command:=CMD_WRITE
writereq.data:=string
writereq.length:=-1 -> This means print until terminating NIL
DoIO(writereq)
ENDPROC
->>>
->>> PROC queueRead(readreq:PTR TO iostd, whereto)
-> Queue up a read request to console, passing it pointer to a buffer into
-> which it can read the character
PROC queueRead(readreq:PTR TO iostd, whereto)
readreq.command:=CMD_READ
readreq.data:=whereto
readreq.length:=1
SendIO(readreq)
ENDPROC
->>>
->>> PROC conMayGetChar(msgport, whereto)
-> Check if a character has been received. If none, return -1
PROC conMayGetChar(msgport, whereto)
DEF temp, readreq:PTR TO iostd
IF NIL=(readreq:=GetMsg(msgport)) THEN RETURN -1
temp:=whereto[] -> Get the character...
queueRead(readreq, whereto) -> ...then re-use the request block
ENDPROC temp
->>>